<?php
namespace app\components\pay;

use Yii;
use yii\base\Exception;

use app\components\Func;

use app\models\Shop;

/**
 * 支付宝
 */
class Alipay extends Pay
{
    const PAY_URL = 'https://mapi.alipay.com/gateway.do';

    static private $payQr;
    
    //预支付
    public function prepay(array $paras) {
        if(!isset($paras['subject'])) throw new \Exception('subject为空',2022023);
        if(!isset($paras['out_trade_no'])) throw new \Exception('out_trade_no为空',2022015);
        if(!isset($paras['total_fee'])) throw new \Exception('total_fee为空',2022016);
        if(!isset($paras['notify_url'])) throw new \Exception('notify_url为空');
        $paras['service'] = 'alipay.acquire.precreate';
        $paras['partner'] = $this->paymentObj->partner_id;
        $paras['_input_charset'] = 'utf-8';
        $paras['product_code'] = 'QR_CODE_OFFLINE';
        $paras['seller_id'] = $this->paymentObj->partner_id;
        $paras['price'] = $paras['total_fee'];
        $paras['quantity'] = 1;
        $paras['goods_detail'] = ''; //商品明细
        $paras['it_b_pay'] = '10m';
        $paras['extend_params']['AGENT_ID'] = '8708198h1';
        $paras['extend_params']['TERMINAL_ID'] = 'dev0001';
        return $this->getData($paras);
    }

    //统一下单支付,适用于被扫支付
    public function micropay(array $paras) {
        if(!isset($paras['subject'])) throw new \Exception('subject为空',2022023);
        if(!isset($paras['out_trade_no'])) throw new \Exception('out_trade_no为空',2022015);
        if(!isset($paras['total_fee'])) throw new \Exception('total_fee为空',2022016);
        if(!isset($paras['notify_url'])) throw new \Exception('notify_url为空',2022024);
        if(!isset($paras['dynamic_id'])) throw new \Exception('dynamic_id为空',2022025);
        $paras['service'] = 'alipay.acquire.createandpay';
        $paras['partner'] = $this->paymentObj->partner_id;
        $paras['_input_charset'] = 'utf-8';
        $paras['product_code'] = 'BARCODE_PAY_OFFLINE';
        $paras['dynamic_id_type'] = 'qr_code';
        $paras['it_b_pay'] = '10m';
        $paras['extend_params']['AGENT_ID'] = '8708198h1';
        $paras['extend_params']['TERMINAL_ID'] = 'dev0001';

        return $this->getData($paras);
    }
    //定单查询
    public function orderquery(array $paras)
    {
        if(!isset($paras['out_trade_no']))throw new \Exception('out_trade_no为空',2022015);
        $paras['service'] = 'alipay.acquire.query';
        $paras['partner'] = $this->paymentObj->partner_id;
        if(!isset($paras['_input_charset']))$paras['_input_charset'] = 'utf-8';
        return $this->getData($paras);
    }
    
    //退款
    public function refund(array $paras) {
        if(!isset($paras['trade_no'])) throw new \Exception('trade_no为空',2022026);
        if(!isset($paras['refund_amount'])) throw new \Exception('refund_amount为空',2022021);
        if(!isset($paras['refund_reason'])) throw new \Exception('refund_reason为空',2022022);  //退款原因:设备号,标识客来乐设备退款
        $paras['service'] = 'alipay.acquire.refund';
        $paras['partner'] = $this->paymentObj->partner_id;
        $paras['_input_charset'] = 'utf-8';
        $paras['out_trade_no'] = time(); //随机传的，以trade_no为准
        $paras['out_request_no'] = Func::getcode(10);
        $sign_arr = $this->getSign($paras);
        $request = http_build_query($sign_arr);
        $result = @Func::file_get_contents(self::PAY_URL . '?' . $request);
        if(empty($result)) throw new \Exception('支付宝接口提示:可能是超时', 2022001);
        $result_arr = Func::xmlToArray($result);
        if ($result_arr['is_success'] == 'F') {
            throw new \Exception('支付宝接口错误:'.$result_arr['error'],2022001);
        }
        if ($result_arr['response']['alipay']['result_code'] != 'SUCCESS') {
            throw new \Exception('支付宝接口错误:'.$result_arr['response']['alipay']['detail_error_des'],2022001);
        }
        return [
            'refund_trade_no' => $paras['out_request_no'],
            'refund_trade_id' => $result_arr['response']['alipay']['trade_no'],
        ];
    }
    
    //退款
    public function refundquery(array $paras)
    {
        return ;
    }
    
    //收单撤销接口
    public function cancel(array $paras) {
        if(!isset($paras['out_trade_no'])) throw new \Exception('out_trade_no为空',2022015);
        $paras['service'] = 'alipay.acquire.cancel';
        $paras['partner'] = $this->paymentObj->partner_id;
        $paras['_input_charset'] = 'utf-8';
        return $this->getData($paras);
    }
    
    //签名
    public function getSign($obj) {
        $arr = [];
        foreach ($obj as $k => $v){
            $arr[$k] = is_array($v) ? json_encode($v) : (string)$v;
        }
        $arr = array_filter($arr);
        unset($arr['sign']);
        unset($arr['sign_type']);
        //签名步骤一：按字典序排序参数
        ksort($arr, SORT_STRING);
        $sign_str = Func::http_build_str($arr).$this->partner_key;
        $arr['sign_type'] = 'MD5';
        $arr['sign'] = md5($sign_str);
        return $arr;
    }
    
    public function checkNotifySign($arr) {
        $sign = $arr['sign'];
        $get_arr = $this->getSign($arr);
        return $sign == $get_arr['sign'];
    }
    
    //获取接口数据
    public function getData($paras) {
        $sign_arr = $this->getSign($paras);
        $request = http_build_query($sign_arr);
        $result = @Func::file_get_contents(self::PAY_URL . '?' . $request);
        if(empty($result)) throw new \Exception('支付宝接口提示:可能是超时', 2022001);
        $result_arr = Func::xmlToArray($result);
        if ($result_arr['is_success'] != 'T') {
            throw new \Exception('支付宝接口错误:'.$result_arr['error'],2022001);
        }
        $arr = $result_arr['response']['alipay'];
        
        return $arr;
    }
    
    public function getPayQr($order) {
        if(!empty(self::$payQr)) return self::$payQr;
        //如果是畅源单独处理，临时性的
        if (Func::isChy($order->enterprise_id)) {
            self::$payQr = $this->getChyAlipayQrCode($order);
            return self::$payQr;
        }
        $params = [
            'subject' => $order->shop->name,
            'out_trade_no' => $order->our_trade_no,
            'total_fee' => $order->getMustFee(),
            'notify_url' => Yii::$app->urlManager->createAbsoluteUrl('pay/alipaynotify'),
        ];

        $appObjAlipay = $order->getAppUseObj(App::APP_ALIPAY)->getConfigObj();
        $storeId = $appObjAlipay->getAttributeValue('store_id');
        if(!empty($storeId)) {
            $params['extend_params']['STORE_ID'] = $storeId;
        }
        $result = $this->prepay($params);
        if ($result['result_code'] != 'SUCCESS') {
            throw new \Exception('支付宝接口错误:'.$result['detail_error_des'],2022001);
        }
        self::$payQr = $result['qr_code'];
        
        return self::$payQr;
    }
    

    
}